﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace MCorder.motor
{
	public partial class PCI8932
	{
		//#################### AD硬件参数PCI8932_PARA_AD定义 #####################
		// 用于AD采样的实际硬件参数
		public struct PCI8932_PARA_AD
		{
			public Int32 FirstChannel;      // 首通道[0, 15]
			public Int32 LastChannel;       // 末通道[0, 15],要求末通道必须大于或等于首通道
			public Int32 InputRange;        // 模拟量输入量程范围,其取值请见下面相关常量定义
			public Int32 GroundingMode;     // 接地方式(单端或双端选择),其取值请见下面相关常量定义
			public Int32 Gains;
		}

		//***********************************************************
		// AD硬件参数PCI8932_PARA_AD中的InputRange模拟量输入范围所使用的选项
		public const Int32 PCI8932_INPUT_N10000_P10000mV = 0x00; // ±10000mV
		public const Int32 PCI8932_INPUT_N5000_P5000mV = 0x01; // ±5000mV
		public const Int32 PCI8932_INPUT_N2500_P2500mV = 0x02; // ±2500mV
		public const Int32 PCI8932_INPUT_0_P10000mV = 0x03; // 0～10000mV

		//***********************************************************
		// AD参数PCI8932_PARA_AD中的Gains使用的硬件增益选项
		public const Int32 PCI8932_GAINS_1MULT = 0x00; // 1倍增益
		public const Int32 PCI8932_GAINS_2MULT = 0x01; // 2倍增益
		public const Int32 PCI8932_GAINS_4MULT = 0x02; // 4倍增益
		public const Int32 PCI8932_GAINS_8MULT = 0x03; // 8倍增益

		//***********************************************************
		// AD参数PCI8932_PARA_AD中的GroundingMode使用的模拟信号接地方式选项
		public const Int32 PCI8932_GNDMODE_SE = 0x00;   // 单端方式(SE:Single end)
		public const Int32 PCI8932_GNDMODE_DI = 0x01;   // 双端方式(DI:Differential)

		//***********************************************************
		// 用于计数器CNT的参数结构
		// 硬件参数ControlMode控制字模式选项
		public const Int32 PCI8932_GATEMODE_POSITIVE_0 = 0x00;      // COUNTER:GATE高电平时计数，低电平时停止计数，计数时重新写入初值，按初值计数
																	// 计数结束产生中断：写入初值开始计数时OUT开始为0，当计数到0时OUT为1

		public const Int32 PCI8932_GATEMODE_RISING_1 = 0x01;        // COUNTER:GATE上边沿触发计数，计数中出现GATE上升沿重新装入初值计数
																	// 可编程单拍脉冲：当写入初值时OUT为1，当开始计数时OUT为0，当计数到0时OUT再次为1

		public const Int32 PCI8932_GATEMODE_POSITIVE_2 = 0x02;      // COUNTER:GATE高电平时计数，低电平时停止计数，计数时重新写入初值，按初值计数
																	// 频率发生器：计数期间OUT为1，计数到0后输出一个周期的0，并重新装入计数值计数

		public const Int32 PCI8932_GATEMODE_POSITIVE_3 = 0x03;      // COUNTER:GATE高电平时计数，低电平时停止计数，计数时重新写入初值，按初值计数
																	// 方波发生器：计数期间OUT为1，计数到0后输出一个周期的0，并重新装入计数值计数

		public const Int32 PCI8932_GATEMODE_POSITIVE_4 = 0x04;      // COUNTER:GATE高电平时计数，低电平时停止计数，计数时重新写入初值，按初值计数
																	// 软件触发选通：写入初值OUT为1， 计数结束OUT输出一个周期低电平信号

		public const Int32 PCI8932_GATEMODE_RISING_5 = 0x05;        // COUNTER:GATE上边沿触发计数，计数中出现GATE上升沿重新装入初值计数
																	// 硬件触发选通：写入初值OUT为1， 计数结束OUT输出一个周期低电平信号



		//***********************************************************
		// 用户函数接口

		//######################## 设备对象管理函数 ##############################
		[DllImport("PCI8932_32.DLL")]
		public static extern IntPtr PCI8932_CreateDevice(Int32 DeviceLgcID);       // 用逻辑号创建设备对象
		[DllImport("PCI8932_32.DLL")]
		public static extern IntPtr PCI8932_CreateDeviceEx(Int32 DevicePhysID);     // 用物理号创建设备对象
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDeviceCount(IntPtr hDevice);          // 取得设备总台数
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDeviceCurrentID(IntPtr hDevice, ref Int32 DeviceLgcID, ref Int32 DevicePhysID);
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ListDeviceDlg(IntPtr hDevice);           // 以对话框窗体方式列表系统当中的所有的该PCI设备
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ReleaseDevice(IntPtr hDevice);           // 仅释放设备对象

		//####################### AD数据读取函数 #################################
		// 适于大多数普通用户，这些接口最简单、最快捷、最可靠，让用户不必知道设备
		// 低层复杂的硬件控制协议和繁多的软件控制编程，仅用下面的初始化设备和读取
		// AD数据两个函数便能轻松高效地实现高速、连续的数据采集

		// AD函数
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_InitDeviceAD(                // 初始化设备，当返回TRUE后,设备即准备就绪.
										IntPtr hDevice,                 // 设备对象,它由CreateDevice函数创建
										ref PCI8932_PARA_AD pADPara);   // 硬件参数, 它仅在此函数中决定硬件状态
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ReadDeviceAD(                // 当AD标志有效时，用此函数读取设备上的AD数据(程序非空方式)
										IntPtr hDevice,                 // 设备句柄,它由CreateDevice函数创建
										UInt16[] ADBuffer,              // 接受原始AD数据的用户缓冲区
										Int32 nReadSizeWords,           // 相对于偏位点后读入的数据长度(字)
										ref Int32 nRetSizeWords);       // 返回实际读取的长度(字)
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ReleaseDeviceAD(             // 关闭AD设备,禁止传输,且释放资源
										IntPtr hDevice);                // 设备句柄,它由CreateDevice函数创建

		//##################### AD的硬件参数操作函数 ###########################
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_SaveParaAD(IntPtr hDevice, ref PCI8932_PARA_AD pADPara); // 将当前的AD采样参数保存至系统中
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_LoadParaAD(IntPtr hDevice, ref PCI8932_PARA_AD pADPara); // 将AD采样参数从系统中读出
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ResetParaAD(IntPtr hDevice, ref PCI8932_PARA_AD pADPara); // 将AD采样参数恢复至出厂默认值

		//####################### DA数据输出函数 #################################
		// 适于大多数普通用户，这些接口最简单、最快捷、最可靠，让用户不必知道设备
		// 低层复杂的硬件控制协议和繁多的软件控制编程，仅用下面其中几个函数便能轻
		// 松实现DA数据输出
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WriteDeviceDA(               // 输出DA原始数据到CN1上的AO0-AO3上
											IntPtr hDevice,             // 设备句柄,它应由CreateDevice函数创建
											Int16 nDAData,              // DA的原始码数据,取值范围为[0, 4095]
											Int32 nDAChannel);          // DA通道号(0-3)

		//##################### 计数器控制函数 ##########################
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_SetDeviceCNT(                // 初始化计数器
											IntPtr hDevice,         // 设备句柄
											UInt32 ContrlMode,          // 计数器控制模式
											UInt32 CNTVal,              // 计数初值
											UInt32 ulChannel);          // 通道选择[0-2]			
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDeviceCNT(                // 取得各路计数器的当前计数值
											IntPtr hDevice,         // 设备对象句柄,它由CreateDevice函数创建
											ref UInt32 pCNTVal,     // 返回计数值
											UInt32 ulChannel);          // 通道选择[0-2]

		//####################### 数字I/O输入输出函数 #################################
		// 用户可以使用WriteRegisterUInt32和ReadRegisterUInt32等函数直接控制寄存器进行I/O
		// 输入输出，但使用下面两个函数更省事，它不需要您关心寄存器分配和位操作等，而只
		// 需象VB等语言的属性操作那么简单地实现各开关量通道的控制。
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_SetDeviceDO(             // 输出开关量状态
												IntPtr hDevice,     // 设备句柄								        
												Byte[] bDOSts);     // 开关状态

		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDeviceDI(             // 取得开关量状态     
												IntPtr hDevice,     // 设备句柄								        
												Byte[] bDISts);     // 开关状态
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_RetDeviceDO(             // 回读开关量输出状态
											IntPtr hDevice,         // 设备对象句柄,它由CreateDevice函数创建        
											Byte[] bDOSts);         // 获得开关输出状态(注意: 必须定义为8个字节元素的数组)

		//################# 内存映射寄存器直接操作及读写函数 ########################
		// 适用于用户对本设备更直接、更特殊、更低层、更复杂的控制。比如根据特殊的

		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDeviceBar(            // 取得指定的指定设备寄存器组BAR地址
										IntPtr hDevice,             // 设备对象句柄,它由CreateDevice函数创建
										UInt32[] pulPCIBar);        // 返回PCI BAR所有地址,具体PCI BAR中有多少可用地址请看硬件说明书
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_GetDevVersion(           // 获取设备固件及程序版本
										IntPtr hDevice,             // 设备对象句柄,它由CreateDevice函数创建
										ref UInt32 pulFmwVersion,   // 固件版本
										ref UInt32 pulDriverVersion);// 驱动版本
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WriteRegisterByte(       // 往指定寄存器空间位置写入单节字数据
										IntPtr hDevice,             // 设备对象句柄,它由CreateDevice函数创建
										UInt32 LinearAddr,          // 指定寄存器的线性基地址,它等于GetDeviceAddr中的LinearAddr参数返回值
										UInt32 OffsetBytes,         // 相对于线性基地址基地址的偏移位置(字节)
										Byte Value);                // 往指定地址写入单字节数据（其地址由线性基地址和偏移位置决定）
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WriteRegisterWord(       // 写双字节数据（其余同上）
										IntPtr hDevice,
										UInt32 LinearAddr,
										UInt32 OffsetBytes,
										UInt16 Value);
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WriteRegisterULong(      // 写四节字数据（其余同上）
										IntPtr hDevice,
										UInt32 LinearAddr,
										UInt32 OffsetBytes,
										UInt32 Value);
		[DllImport("PCI8932_32.DLL")]
		public static extern Byte PCI8932_ReadRegisterByte(         // 读入单字节数据（其余同上）
										IntPtr hDevice,
										UInt32 LinearAddr,
										UInt32 OffsetBytes);
		[DllImport("PCI8932_32.DLL")]
		public static extern UInt16 PCI8932_ReadRegisterWord(       // 读入双字节数据（其余同上）
										IntPtr hDevice,
										UInt32 LinearAddr,
										UInt32 OffsetBytes);
		[DllImport("PCI8932_32.DLL")]
		public static extern UInt32 PCI8932_ReadRegisterULong(      // 读入四字节数据（其余同上）
										IntPtr hDevice,
										UInt32 LinearAddr,
										UInt32 OffsetBytes);

		//################# I/O端口直接操作及读写函数 ########################
		// 适用于用户对本设备更直接、更特殊、更低层、更复杂的控制。比如根据特殊的
		// 控制对象需要特殊的控制流程和控制效率时，则用户可以使用这些接口予以实现。
		// 但这些函数主要适用于传统设备，如ISA总线、并口、串口等设备，不能用于本PCI设备
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WritePortByte(           // 8位写端口
										IntPtr hDevice,             // 设备句柄(由CreateDevice创建)
										UInt32 nPort,               // 端口地址
										Byte Value);                // 写出的8位整型数据
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WritePortWord(IntPtr hDevice, UInt32 nPort, UInt16 Value);
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_WritePortULong(IntPtr hDevice, UInt32 nPort, UInt32 Value);
		[DllImport("PCI8932_32.DLL")]
		public static extern Byte PCI8932_ReadPortByte(IntPtr hDevice, UInt32 nPort);
		[DllImport("PCI8932_32.DLL")]
		public static extern UInt16 PCI8932_ReadPortWord(IntPtr hDevice, UInt32 nPort);
		[DllImport("PCI8932_32.DLL")]
		public static extern UInt32 PCI8932_ReadPortULong(IntPtr hDevice, UInt32 nPort);
		// 如果您要在用户模式下，直接访问硬件端口，请安装并使用ISA\CommUser下的驱动ReadPortByteEx等函数

		//########################### 线程操作函数 ######################################
		[DllImport("PCI8932_32.DLL")]
		public static extern IntPtr PCI8932_CreateSystemEvent(); // 创建内核事件对象，供InitDeviceDmaAD和VB子线程等函数使用
		[DllImport("PCI8932_32.DLL")]
		public static extern Int32 PCI8932_ReleaseSystemEvent(IntPtr hEvent); // 释放内核事件对象


	}
}
